.macro constructor
DROP
GETGLOB 1
ISNULL
IFREF {
	CALL $c4_to_c7_with_init_storage$
}
;; constructor protection
GETGLOB 6
THROWIF 51
PUSHINT 1
SETGLOB 6
;; end constructor protection
; Decode input parameters
ENDS
; constructor verification
GETGLOB 2
THROWIFNOT 101
GETGLOB 5
DUP
ISNULL
PUSHCONT {
	DROP
	PUSHINT 0
}
IF
;; ==
GETGLOB 2
EQUAL
THROWIFNOT 102
ACCEPT
; end constructor verification
CALLREF {
	CALL $c7_to_c4$
}
TRUE
SETGLOB 7

.macro verify
DROP
GETGLOB 1
ISNULL
IFREF {
	CALL $c4_to_c7$
}
; Decode input parameters
; Decode value
LDREF
ENDS
;; param: value
CALLREF {
	CALL $verify_internal_macro$
}
;; emitting 1 value(s)
PUSH S1
EQINT -1
PUSHCONT {
	PUSH S3
	CTOS
	LDU 2
	LDMSGADDR
	DROP
	NIP
	NEWC
	STSLICECONST xc
	STSLICE
	PUSHSLICE x000000000000000000000000224839b5a_
	STSLICER
	PUSH S1
	STIR 1
	ENDC
	PUSHINT 0
	SENDRAWMSG
}
IF
DROP
CALLREF {
	CALL $c7_to_c4$
}
TRUE
SETGLOB 7

.globl	verify_internal
.type	verify_internal, @function
CALL $verify_internal_macro$

.macro verify_internal_macro
;; param: value
; function verify
NEWC
;; decl: builder
; expValue
; end expValue
;; push identifier value
PUSH2 S0, S1
STREFR
; colValue
NIP
; end colValue
;; return
;; push identifier builder
ENDC
VERGRTH16
; end function verify
NIP

.macro c7_to_c4
GETGLOB 2
NEWC
STU 256
GETGLOB 3
STUR 64
GETGLOB 6
STUR 1
ENDC
POP C4

.macro c4_to_c7
PUSHROOT
CTOS        ; c4
LDU 256      ; pubkey c4
LDU 64      ; pubkey timestamp c4
LDU 1       ; pubkey [timestamp] constructor_flag memory
ENDS
TRUE
SETGLOB 1   ; pubkey [timestamp] constructor_flag
SETGLOB 6   ; pubkey [timestamp]
SETGLOB 3   ; D
SETGLOB 2

.macro c4_to_c7_with_init_storage
PUSHROOT
CTOS        ; c4
DUP        ; c4 c4
SBITS      ; c4 bits
GTINT 1    ; c4 bits>1
PUSHCONT {
	LDU 256      ; pubkey c4
	LDU 64      ; pubkey timestamp c4
	LDU 1       ; pubkey [timestamp] constructor_flag memory
	ENDS
	TRUE
	SETGLOB 1   ; pubkey [timestamp] constructor_flag
	SETGLOB 6   ; pubkey [timestamp]
	SETGLOB 3   ; D
	SETGLOB 2
}
PUSHCONT {
	PLDDICT   ; D
	; set contract pubkey
	PUSHINT 0
	SWAP
	PUSHINT 64
	DICTUGET
	THROWIFNOT 61
	PLDU 256
	SETGLOB 2
	PUSHINT 0 ; timestamp
	SETGLOB 3
	PUSHINT 0 ; constructor_flag
	SETGLOB 6
	TRUE
	SETGLOB 1
}
IFELSE

.internal-alias :main_internal, 0
.internal :main_internal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Function: main_internal
;; param: contract_balance
;; param: msg_balance
;; param: int_msg_info
;; param: msg_body_slice
;; param: transaction_type
PUSH S2
CTOS
PLDU 4
MODPOW2 1
IFRET
PUSH S1    ; body
SEMPTY     ; isEmpty
IFRET
PUSH S1 ; body
LDUQ 32  ; [funcId] body' ok
THROWIFNOT 60 ; funcId body'
PUSH S1 ; funcId body' funcId
IFNOTRET
SWAP
CALLREF {
	CALL $public_function_selector$
}
GETGLOB 7
ISNULL
THROWIF 60

.internal-alias :main_external, -1
.internal :main_external
PUSH S1
CALLREF {
	CALL $c4_to_c7_with_init_storage$
}
LDU 1 ; haveSign msgSlice
SWAP
PUSHCONT {
	PUSHINT 512
	LDSLICEX ; signatureSlice msgSlice
	DUP      ; signatureSlice msgSlice msgSlice
	HASHSU   ; signatureSlice msgSlice hashMsgSlice
	ROT
	GETGLOB 2
	DUP
	SETGLOB 5
	CHKSIGNU      ; msgSlice isSigned
	THROWIFNOT 40 ; msgSlice
}
IF
LDU 64                         ; timestamp msgSlice
SWAP                           ; msgSlice timestamp
CALL $replay_protection_macro$ ; msgSlice
LDU 32  ; expireAt msgSlice
SWAP    ; msgSlice expireAt
NOW     ; msgSlice expireAt now
GREATER ; msgSlice expireAt>now
THROWIFNOT 57
LDU  32 ; funcId body
SWAP    ; body funcId
CALLREF {
	CALL $public_function_selector$
}
GETGLOB 7
ISNULL
THROWIF 60

.macro public_function_selector
DUP
PUSHINT 153151190
EQUAL
IFJMPREF {
	CALL $verify$
}
DUP
PUSHINT 1756716863
EQUAL
IFJMPREF {
	CALL $constructor$
}
